/*++

Copyright (c) 2007  Microsoft Corporation 

Filename: 

    Application.cs

Abstract: 

    This file is an Interface for Visio application
     
--*/

#region References
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Globalization;
using Visio = Microsoft.Office.Interop.Visio;
using System.Windows.Forms;
using UtilityManager;
using RackServerManager;
using AddIn.Windows.Forms;
using System.IO;
using System.Diagnostics;
#endregion References

namespace VisioManager
{
    /// <summary>
    /// Interface for Visio application
    /// </summary>
    class Application
    {
        #region Private variables

        //Table to store all open document reference
        private static Hashtable RackServerDocuments;

        #endregion        

        #region Constructors

        /// <summary>
        /// Default Constructor.
        /// </summary>
        public Application()
        {
            //Left blank
        }

        /// <summary>
        /// Constructor - overridden.
        /// </summary>
        /// <param name="visioApplication">
        ///  Visio application reference
        /// </param>
        public Application(Visio.Application visioApplication)
        {
            if (visioApplication == null)
            {
                return;
            }

            try
            {
                // Table to store all documents
                RackServerDocuments = new Hashtable();

                // Initializa events and data tables
                Global.VisioApp = visioApplication;
                SetupVisioEvents();
            }
            catch (RackException ex)
            {
                // To catch exceptions from current functions
                throw new RackException("Application Constructor", ex.InnerException);
            }
            catch (Exception ex)
            {
                // To catch exceptions from current functions
                throw new RackException("Application Constructor", ex);
            }
        }

        #endregion

        #region Events

        /// <summary>
        /// Before Document Close Event
        /// </summary>
        /// <param name="visioDocument"></param>
        void VisioApp_BeforeDocumentClose(Visio.Document visioDocument)
        {
            try
            {
                // get the document name
                string fullName = visioDocument.FullName.ToLower(CultureInfo.CurrentCulture);

                if (fullName.EndsWith(".vss") ||
                    fullName.EndsWith(".vsx") ||
                    visioDocument.Type == Visio.VisDocumentTypes.visTypeStencil)
                {
                    // do not create a document wrapper for this document
                    return;
                }

                if (!Convert.ToBoolean((short)visioDocument.DocumentSheet.get_CellExistsU(
                                      Global.DocTemplateUserProp, 0)))
                {
                    // Consider documents created using Server Virtualization template only
                    return;
                }

                // Look through the document wrapper classes and find the one the corresponds with
                // the Visio document that is closing.
                Document docToRemove = GetDocumentObject(visioDocument);

                // If we found a document wrapper, then remove it from our collection.
                if (docToRemove != null)
                {
                    RackServerDocuments.Remove(docToRemove.UniqueID);
                }
            }
            catch (Exception ex)
            {
                RackException.HandleExceptions(ex);
            }
        }

        /// <summary>
        /// Event to handle Document Created or Opened
        /// </summary>
        /// <param name="visioDocument"></param>
        void VisioApp_DocumentCreatedOpened(Visio.Document visioDocument)
        {
            try
            {
                // get the document name
                string fullName = visioDocument.FullName.ToLower(CultureInfo.CurrentCulture);

                if (fullName.EndsWith(".vss") ||
                    fullName.EndsWith(".vsx") ||
                    visioDocument.Type == Visio.VisDocumentTypes.visTypeStencil)
                {
                    // do not create a document wrapper for this document
                    return;
                }

                if (!Convert.ToBoolean((short)visioDocument.DocumentSheet.get_CellExistsU(
                                                      Global.DocTemplateUserProp, 0)))
                {
                    // Consider documents created using Server Virtualization template only
                    return;
                }

                bool docSavedState = visioDocument.Saved;

                // Create new Document object for new Visio document
                Document newDocument = new Document(visioDocument);

                // add this new document to our collection
                if (newDocument != null)
                {
                    // add the item to the collection
                    RackServerDocuments.Add(newDocument.UniqueID, newDocument);
                    if (!Global.InternalDocOpen)
                    {
                        //Check if document is empty then only open the import data form
                        Visio.Page currPage = visioDocument.Application.ActivePage;

                        string maxServerConsolidate = Global.GetDocumentProperty(visioDocument, "User."+Global.MaxServerConsolidateProp);
                        if (!string.IsNullOrEmpty(maxServerConsolidate))
                        {
                            Global.MaxServerConsolidate = Convert.ToInt32(maxServerConsolidate);
                        }

                        string cpuUsageThreshold=Global.GetDocumentProperty(visioDocument, "User."+Global.CpuUsageThresholdProp);
                        if (!string.IsNullOrEmpty(cpuUsageThreshold))
                        {
                            Global.CpuUsageThreshold = Convert.ToInt32(cpuUsageThreshold);
                        }

                        string serverName = Global.GetDocumentProperty(visioDocument, "User." + Global.ScomServerNameProp);
                        if (!string.IsNullOrEmpty(serverName))
                        {
                            Global.ServerName = serverName;
                        }

                        //string reportServerName = Global.GetDocumentProperty(visioDocument, "User." + Global.ScomReportServerNameProp);
                        //if (!string.IsNullOrEmpty(reportServerName))
                        //{
                        //    Global.ReportServerName = reportServerName;
                        //}

                        //string opsDBName = Global.GetDocumentProperty(visioDocument, "User." + Global.ScomDatabaseNameProp);
                        //if (!string.IsNullOrEmpty(opsDBName))
                        //{
                        //    Global.OpsDBName = opsDBName;
                        //}

                        //string reportingDBName = Global.GetDocumentProperty(visioDocument, "User." + Global.ReportingDatabaseNameProp);
                        //if (!string.IsNullOrEmpty(reportingDBName))
                        //{
                        //    Global.OpsReportingDBName = reportingDBName;
                        //}

                        string userName = Global.GetDocumentProperty(visioDocument, "User." + Global.UserNameProp);
                        if (!string.IsNullOrEmpty(userName))
                        {
                            Global.UserName = userName;
                        }

                        string windowsAuthentication = Global.GetDocumentProperty(visioDocument, "User." + Global.WindowsAuthenticationProp);
                        if (!string.IsNullOrEmpty(windowsAuthentication))
                        {
                            Global.WindowsAuthentication = Convert.ToBoolean(windowsAuthentication);
                        }
                        string userCredentials = Global.GetDocumentProperty(visioDocument, "User." + Global.UserCredentialsProp);
                        if (!string.IsNullOrEmpty(userCredentials))
                        {
                            Global.UserCredentials = Convert.ToBoolean(userCredentials);
                            //Global.UserName = String.Empty;
                            Global.Password = String.Empty;
                        }
                        string dtOptions = Global.GetDocumentProperty(visioDocument, "User."+Global.DataOptionProp);
                        if (!string.IsNullOrEmpty(dtOptions))
                        {
                            if (string.Compare(dtOptions, Global.DataOption.Scom.ToString(), true, CultureInfo.InvariantCulture) == 0)
                            {
                                Global.DTOption = Global.DataOption.Scom;
                            }
                            else if (string.Compare(dtOptions, Global.DataOption.Wmi.ToString(), true, CultureInfo.InvariantCulture) == 0)
                            {
                                Global.DTOption = Global.DataOption.Wmi;
                            }
                        }  
                  
                        if (visioDocument.Pages.Count <= 1 &&
                               (currPage != null && currPage.Shapes.Count == 0))
                        {
                            newDocument.ImportData();
                        }

                    }

                }

                // reset the saved state of the document after we have done our work
                visioDocument.Saved = docSavedState;
            }
            catch (RackException ex)
            {
                // To catch and display exceptions from sub functions
                RackException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex.InnerException);
            }
            catch (Exception ex)
            {
                // To catch exceptions from current functions
                RackException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex);
            }
        }

        /// <summary>
        /// Visio marker event for application
        /// </summary>
        /// <param name="app"></param>
        /// <param name="SequenceNum"></param>
        /// <param name="ContextString"></param>
        internal void vsoApplication_MarkerEvent(Visio.Application visioApplication,
            int SequenceNum, string ContextString)
        {
            Visio.Document visioDocument = null;
            Visio.Page visioPage = null;
            Visio.Shape visioShape = null;
            string appid = null;
            string cmd = null;

            try
            {
                // Check if valid arguments exist
                if (String.IsNullOrEmpty(ContextString))
                    return;

                // Get the visio objects from the context string
                Global.GetVisioObjects(ContextString, visioApplication, ref visioDocument,
                    ref visioPage, ref visioShape, ref appid, ref cmd);

                // If event not raise for rack server return
                if (String.Compare(appid, Global.ApplicationId) != 0)
                    return;

                switch (cmd)
                {
                    case Global.CommandStringConfigure:
                        ConfigureAddin();
                        break;

                    case Global.CommandStringHelp:
                        try
                        {
                            string helpFileName = Global.AppPath() + "Help\\User Guide for Visio Add-In for Rack Server Virtualization.pdf";
                            if (File.Exists(helpFileName))
                            {
                                FileInfo helpFile = new FileInfo(helpFileName);
                                Process word = new Process();
                                word.StartInfo.FileName = helpFile.FullName;
                                word.Start();
                            }
                            else
                            {
                                MessageBox.Show(String.Format(CultureInfo.CurrentCulture,Global.GetResourceString("StrHelpFIleNotFound"),
                                    helpFileName),
                                    Global.GetResourceString("MessageBoxCaption"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Error,
                                    MessageBoxDefaultButton.Button1);
                            }
                        }
                        catch (System.ComponentModel.Win32Exception ex)
                        {
                            if (ex.NativeErrorCode == 1155) // Message.Contains(Global.GetResourceString("PDF_Viewer_Exception")))
                            {
                                MessageBox.Show(Global.GetResourceString("PDF_Viewer_Error"),
                                    Global.GetResourceString("MessageBoxCaption"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Error,
                                    MessageBoxDefaultButton.Button1);
                            }
                        }
                        break;

                    case Global.CommandStringAbout:
                        using (AboutForm abtFrm = new AboutForm())
                        {
                            abtFrm.ShowDialog();
                        }
                        //Form will be disposed at the end of using
                        break;

                    default:
                        break;
                }
            }
            catch (RackException ex)
            {
                // To catch and display exceptions from sub functions
                RackException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                             Global.GetResourceString("Exception_UsrMsg"), ex.InnerException);
            }
            catch (Exception ex)
            {
                // To catch exceptions from current functions
                RackException.HandleExceptions(Global.GetResourceString("Exception_MsgBox_Caption"),
                            Global.GetResourceString("Exception_UsrMsg"), ex);
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Setup the event sinks to the Visio.Application class.
        /// </summary>
        private void SetupVisioEvents()
        {
            try
            {
                // setup the delegates for the Visio.Application object
                Global.VisioApp.MarkerEvent += new 
                    Visio.EApplication_MarkerEventEventHandler
                    (vsoApplication_MarkerEvent);
                Global.VisioApp.DocumentCreated += new 
                    Microsoft.Office.Interop.Visio.EApplication_DocumentCreatedEventHandler
                    (VisioApp_DocumentCreatedOpened);
                Global.VisioApp.DocumentOpened += new 
                    Microsoft.Office.Interop.Visio.EApplication_DocumentOpenedEventHandler
                    (VisioApp_DocumentCreatedOpened);
                Global.VisioApp.BeforeDocumentClose += new 
                    Microsoft.Office.Interop.Visio.EApplication_BeforeDocumentCloseEventHandler
                    (VisioApp_BeforeDocumentClose);
            }
            catch (Exception ex)
            {
                // To catch exceptions from current functions
                throw new RackException("Setup application events", ex);
            }
            return;
        }

        /// <summary>
        /// Fetch the reference to Document object from the hashtable
        /// </summary>
        /// <param name="visioDocument"></param>
        /// <returns></returns>
        internal static Document GetDocumentObject(Visio.Document visioDocument)
        {
            try
            {
                foreach (Document doc in RackServerDocuments.Values)
                {
                    if (String.Compare(visioDocument.Name, doc.VisioDocument.Name) == 0)
                    {
                        return doc;
                    }
                }
            }
            catch (System.NullReferenceException ex)
            {
                // Handle the error for hash table access
                RackException.HandleExceptions(ex);
            }
            catch (Exception ex)
            {
                // Handle the error for hash table access
                RackException.HandleExceptions(ex);
            }
            return null;
        }

        /// <summary>
        /// Delete visio events before exit
        /// </summary>
        public void DeleteVisioEvents()
        {
            // Clear application events
            Global.VisioApp.MarkerEvent -= vsoApplication_MarkerEvent;
            Global.VisioApp.DocumentCreated -= VisioApp_DocumentCreatedOpened;
            Global.VisioApp.DocumentOpened -= VisioApp_DocumentCreatedOpened;
            Global.VisioApp.BeforeDocumentClose -= VisioApp_BeforeDocumentClose;

            // delete document level events and menu
            foreach (Document doc in RackServerDocuments.Values)
            {
                doc.DeleteVisioEvents();
            }
        }

        /// <summary>
        /// Configure addin
        /// </summary>
        public static void ConfigureAddin()
        {
            using (FrmConfig config = new FrmConfig())
            {
                config.ShowDialog();
            }
        }

        #endregion
    }
}
